package game;

import java.util.ArrayList;
import java.util.Deque;
import java.util.List;

public class Tri {

	public Vertex vertices[] = new Vertex[3];
	
	public List<Tri> adjacency = new ArrayList<Tri>();
	
	public int id = -1;
	
	public boolean processed = false;

	/**
	 * works only on fully triangulated, watertight models, where each
	 * vertex is connected to at least three triangles.
	 * 
	 * Models that are not watertight 
	 * 1. assembled from several separate meshes
	 * 2. open meshes
	 * cannot be preprocessed into the needed form easily
	 * 
	 * Models made up of quads or even more complicated polygons have to the
	 * fully triangulated
	 * 
	 * if a model stores one vertex using several v lines, all those v lines
	 * have to be collapsed into a single v line  
	 * 
	 * @param deque
	 */
	public void computeAdjacency(Deque<Tri> deque) {
		
		//System.out.println("computeAdjacency " + this.id);
		
		for (int i = 0; i < 3; i++) {			
			
			int j = (i + 1) % 3;
			
			Vertex vertexA = vertices[i];
			
			Vertex vertexB = vertices[j];
			
			Tri otherTri = findOtherTri(vertexA, vertexB);
			
			adjacency.add(otherTri);
			
			otherTri.adjacency.add(this);
			
			if (!otherTri.processed) {
				if (!deque.contains(otherTri)) {
					deque.addLast(otherTri);
				}
			}		
			
		}
		
		processed = true;
		
	}

	private Tri findOtherTri(Vertex vertexA, Vertex vertexB) {

		for (Tri outerTri : vertexA.tris) {
			for (Tri innerTri : vertexB.tris) {
				if (outerTri.id == innerTri.id) {
					
					if (outerTri.id == this.id) {
						continue;
					} else {
						return outerTri;
					}
					
				}
			}
		}
		
		//return null;
		
		// if the mesh has a triangle edge, that is not connected to another tri,
		// the mesh is not a closed volumetric form or it is closed and volumetric
		// but it is triangulated in such a way that it does not lend itself to
		// the adjacency algorithm
		//
		// image a cube, where exactly one of the six sides is split into not 2 but
		// 4 triangles. There is at least one tri out of those 4 triangles, that
		// contains a edge which is not met by a edge of the the other sides of the
		// cubes. The edges are colinear, but the other cube side has no splitting
		// vertices that start and end at the same edge with one of the 4 tris edge.
		//
		// *----*----*
		// |   /|   /|
		// |  / |  / |
		// | /  | /  |  side B
		// |/   |/   |
		// *----*----*
		// |       / |
		// | side A  |
		// |/        |
		// *---------*
		//
		// side A does not make use of the splitting vertex of side B. Side A is not
		// fully triangluated. This algorithm will not detect the adjacency of all the
		// tris in side B to tris in side A

		String msg = "Mesh is not fully triangulated! Adjacency algorithm wont work!";
		System.out.println(msg);
		
		//throw new RuntimeException(msg);		
		
		return null;
		
	}

}
